using Assets.Scripts.System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;

public class PlayerController : MonoSingleton<PlayerController>
{
    // 当前帧 hv
    [SerializeField]
    private Vector2 curhv = Vector2.zero;
    IInteractable interactObject = null;
    List<IInteractable> interactWeaponList = new List<IInteractable>();

    [Header("依赖")]
    public GameManager gameManager;
    public StorageSystem storageSystem;
    public PlayerSystem playerSystem;
    public UISystem uiSystem;
    public PlayerAnimController animController;
    public UnityEvent<int> AttackPresseDowndEvent;
    public UnityEvent AttackPressedEvent;
    public UnityEvent<int> AttackPresseUpdEvent;
    public UnityEvent switchWeaponEvent;
    public UnityEvent leaveOrPickUpEvent;
    public UnityEvent WeaponSkillPressedEvent;
    public UnityEvent personSkillPressedEvent;

    private Rigidbody2D rb2D;
    public SpriteRenderer spriteRenderer;
    public PlayerWeaponController weaponController;

    protected override void Awake()
    {
        base.Awake();
        rb2D = GetComponent<Rigidbody2D>();
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Start()
    {
        gameManager = GameManager.Instance;
        storageSystem = StorageSystem.Instance;
        playerSystem = PlayerSystem.Instance;
        uiSystem = UISystem.Instance;
        animController = GetComponent<PlayerAnimController>();
    }
    private void Update()
    {
        if (gameManager.GetCurGamingState() == GameState.Gaming)
        {
            KeystrokeDetection();
            Flip();
        }
    }
    private void FixedUpdate()
    {
        if (gameManager.GetCurGamingState() == GameState.Gaming)
        {
            Move();
        }
    }
    /// <summary>
    /// 按键检测
    /// </summary>
    private void KeystrokeDetection()
    {
        curhv = Util.GetValue2_HorizontalAndVertical();
        animController.SetParameters<float>(ParametersType.Float, "h", Mathf.Abs(rb2D.velocity.x));
        animController.SetParameters<float>(ParametersType.Float, "v", Mathf.Abs(rb2D.velocity.y));
        if (Input.GetKeyDown(storageSystem.storageInfo.attackKeyCode))
        {
            AttackPresseDowndEvent?.Invoke(1);
        }
        if (Input.GetKey(storageSystem.storageInfo.attackKeyCode))
        {
            AttackPressedEvent?.Invoke();
        }
        if (Input.GetKeyUp(storageSystem.storageInfo.attackKeyCode))
        {
            AttackPresseUpdEvent?.Invoke(-1);
        }
        if (Input.GetKeyDown(storageSystem.storageInfo.interactKeyCode))
        {
            interactObject?.Interacte(gameObject);
        }
        if (Input.GetKeyDown(storageSystem.storageInfo.switchWeaponKeyCode))
        {
            switchWeaponEvent?.Invoke();
        }
        if (Input.GetKeyDown(storageSystem.storageInfo.leaveOrPickUpKeyCode))
        {
            leaveOrPickUpEvent?.Invoke();
        }
        if (Input.GetKeyDown(storageSystem.storageInfo.reloadKeyCode))
        {
            weaponController.GetCurWeapon().SendMessage("Reload", SendMessageOptions.DontRequireReceiver);
        }
        if (Input.GetKeyDown(storageSystem.storageInfo.dodgeKeyCode))
        {
            Dodge();
        }
        if (Input.GetKeyDown(storageSystem.storageInfo.weaponSkillKeyCode))
        {

        }
        if (Input.GetKeyDown(storageSystem.storageInfo.personSkillKeyCode))
        {

        }
    }
    private void Move()
    {
        rb2D.AddForce(curhv * playerSystem.data.MoveSpeed * playerSystem.data.MoveSpeedScale, ForceMode2D.Impulse);
    }
    private void Flip()
    {
        Vector2 mouseScreenPos = Util.GetMouseWorldPosition();
        if (transform.position.x <= mouseScreenPos.x)
        {
            transform.localRotation = Quaternion.Euler(0, 0, 0);
        }
        else if (transform.position.x > mouseScreenPos.x)
        {
            transform.localRotation = Quaternion.Euler(0, 180, 0);
        }
    }
    public void AddInteractObject(IInteractable o)
    {
        interactObject = o;
    }
    public void RemoveInteractObject(IInteractable o)
    {
        interactObject = null;
    }
    #region 闪避
    /// <summary>
    /// 闪避
    /// </summary>
    public void Dodge()
    {
        StartCoroutine(Dodge_Coro(playerSystem.dodgeMoveSpeedScale, playerSystem.dodgeDuration));
    }
    private IEnumerator Dodge_Coro(float moveSpeedScale, float duration)
    {
        playerSystem.data.MoveSpeedScale *= moveSpeedScale;
        WaitForSeconds intervalTime = new WaitForSeconds(0.05f);
        while (duration > 0)
        {
            duration -= 0.1f;
            GameObject ghostGO = EffectSystem.Instance.GetParticleEffectByID("10002", transform.position, transform.eulerAngles, transform.localScale, null, true);
            ghostGO.GetComponent<Ghost>().Init(spriteRenderer.sprite);
            yield return intervalTime;
        }
        playerSystem.data.MoveSpeedScale /= moveSpeedScale;
    }
    #endregion
}
